using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.BizTalk.BaseFunctoids;
using System.Reflection;

namespace eliasen.eu.BizTalk.Functoids
{
    class UpperCaseFirstLetter : BaseFunctoid
    {
        public UpperCaseFirstLetter()
            : base()
		{
			//ID for this functoid
            this.ID = 6431;

			// resource assembly must be ProjectName.ResourceName if building with VS.Net
            SetupResourceAssembly("eliasen.eu.BizTalk.Functoids.eliasen.eu.BizTalk.Functoids.Resources", Assembly.GetExecutingAssembly());

			//Setup the Name, ToolTip, Help Description, and the Bitmap for this functoid
            SetName("Str_UpperCaseFirstLetter_Name");
            SetTooltip("Str_UpperCaseFirstLetter_Tooltip");
            SetDescription("Str_UpperCaseFirstLetter_Description");
            SetBitmap("Bmp_UpperCaseFirstLetter_Icon");

			this.SetMinParams(1);
			this.SetMaxParams(2);

            AddInputConnectionType(ConnectionType.All);
            AddInputConnectionType(ConnectionType.All);
			//set the function name that needs to be called when this Functoid is invoked. This means that
			//this Functoid assembly need to be present in GAC for its availability during Test..Map and Runtime.
            SetExternalFunctionName(GetType().Assembly.FullName, "eliasen.eu.BizTalk.Functoids.UpperCaseFirstLetter", "GetUpperCaseFirstLetter");

			//category for this functoid. This functoid goes under the String Functoid Tab in the
			//VS.Net toolbox for functoids.
			this.Category = FunctoidCategory.String;
			this.OutputConnectionType = ConnectionType.AllExceptRecord;
		}
        public string GetUpperCaseFirstLetter(string input)
        {
            return GetUpperCaseFirstLetter(input, null);
        }

		//this is the function that gets called when the Map is executed which has this functoid.
        public string GetUpperCaseFirstLetter(string input, string doNotTouch)
        {
            // Divide the input into substrings that will get treated individually. Don't remove empty strings, because they are needed to insert the spaces between the empty strings later on.
            string[] subStrings = input.Split(" ".ToCharArray(), StringSplitOptions.None);

            // The StringBuiler for the output.
            StringBuilder sb = new StringBuilder();

            //The counter is used to keep track of when the last substring has been reached.
            int counter = 0;

            // for each substring in the input
            foreach (string subString in subStrings)
            {
                if (subString.Length > 0) //Only do something is the string is not empty.
                {
                    bool found = false; // Used to indicate if the substring is found as a string to ignore.
                    string foundString = ""; // Used to contain the string that is to beg ignored.
                    if (doNotTouch != null)
                    {
                        foreach (string dontTouch in doNotTouch.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
                        { // Go through the strings to ignore to see if the curent subString is one of them.
                            if (subString.ToLower() == dontTouch.ToLower()) // Ignore casing when comparing.
                            {
                                found = true; // Indicate that the substring was found as a string to ignore.
                                foundString = dontTouch; // Keep the string that is to be ignored with the casing is should have.
                                break; // Exit the foreach loop.
                            } // if
                        } // foreach
                    }
                    if (found) // If the string was a string to be ignored, add the ignore.string instead of the substring.
                        sb.Append(foundString);
                    else // Convert 
                    {
                        // Uppercase the first character of the string and lowercase the rest.
                        string firstCharacter = subString.ToUpper().Substring(0, 1); //Get the first character of the string.
                        string theRest = "";
                        if (subString.Length > 1)
                            theRest = subString.ToLower().Substring(1, subString.Length - 1);
                        sb.Append(firstCharacter + theRest);
                    }
                    // If we haven't reached the last substring, add a space to the end of the string to keep the correct number of spaces in the string after conversion.
                    if (counter != subStrings.Length - 1)
                        sb.Append(" ");
                }
                else // If the subString was empty, we just add a space, which was filtered away in the split operation.
                    sb.Append(" ");
                counter++;
            }
            return sb.ToString();
        }
    }
}
